package com.dahua.messagesyncsh.service.Impl;

import com.alibaba.fastjson2.JSON;
import com.dahua.messagesyncsh.common.Constants;
import com.dahua.messagesyncsh.config.redis.RedisUtil;
import com.dahua.messagesyncsh.criteria.*;
import com.dahua.messagesyncsh.entity.Equipment;
import com.dahua.messagesyncsh.entity.LatestEquipmentStatus;
import com.dahua.messagesyncsh.mapper.EquipmentMapper;
import com.dahua.messagesyncsh.mapper.SensorMapper;
import com.dahua.messagesyncsh.pojo.EquipmentInfo;
import com.dahua.messagesyncsh.service.EquipmentService;
import com.dahua.messagesyncsh.service.enums.EquipmentSType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import static com.dahua.messagesyncsh.common.Constants.*;

@Slf4j
@Service
public class EquipmentServiceImpl implements EquipmentService {
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private SensorMapper sensorMapper;
    @Resource
    private EquipmentMapper equipmentMapper;


    @Override
    public void caching() {
        redisUtil.deleteKey(EQUIPMENT_ABBREVIATION);
        List<EquipmentInfo> equipments = equipmentMapper.enquire(EquipmentInfoQueryCriteria.builder().registerNumber(ALL).build());
        equipments.forEach(
                (item) -> {
                    if (item.getRegisterNumber() != null && !item.getRegisterNumber().isEmpty()) {
                        redisUtil.setHash(EQUIPMENT_ABBREVIATION, item.getRegisterNumber(), item);
                    }
                }
        );
    }

    @Override
    public EquipmentInfo enquire(String registerNumber) {
        EquipmentInfo info = null;
        //读redis
        try {
            Object hash = redisUtil.getHash(Constants.EQUIPMENT_ABBREVIATION, registerNumber);
            if (hash != null && hash.equals(NULL)) {
                return null;
            }
            info = JSON.parseObject(JSON.toJSONString(hash), EquipmentInfo.class);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        //写redis
        if (info == null) {
            EquipmentInfoQueryCriteria criteria = new EquipmentInfoQueryCriteria();
            /*  上海改成注册代码查询*/
            criteria.setRegisterNumber(registerNumber);
            List<EquipmentInfo> equipmentInfos = equipmentMapper.enquire(criteria);
            if (equipmentInfos.size() == 1) {
                info = equipmentInfos.get(0);
            }

            if (info != null) {
                redisUtil.setHash(EQUIPMENT_ABBREVIATION, registerNumber, info);
            }
            else{
                //避免多次查表，设置空值
                log.error("【查询不到当前设备信息】：{}",registerNumber);
                redisUtil.setHash(EQUIPMENT_ABBREVIATION, registerNumber, NULL);
            }
        }
        return info;
    }

    @Override
    public List<Equipment> detail(EquipmentQueryCriteria criteria) {
        if (criteria.getId() == null && criteria.getName() == null) {
            return equipmentMapper.detail(criteria);
        }

        Equipment info = null;
        try {
            Object hash = null;
            if (criteria.getId() != null) {
                hash = redisUtil.getHash(Constants.EQUIPMENT_DETAIL, String.valueOf(criteria.getId()));
            }else{
                hash = redisUtil.getHash(Constants.EQUIPMENT_DETAIL, criteria.getName());
            }

            if (hash != null && hash.equals(NULL)) {
                hash = null;
            }else{
                info = JSON.parseObject(JSON.toJSONString(hash), Equipment.class);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        if (info == null) {

            List<Equipment> equipments = equipmentMapper.detail(criteria);

            if (!equipments.isEmpty()) {
                Equipment equipment = equipments.get(0);
                redisUtil.setHash(EQUIPMENT_DETAIL, String.valueOf(equipment.getId()), equipment);
                redisUtil.setHash(EQUIPMENT_DETAIL, equipment.getName(), equipment);
                return equipments;
            } else {
                log.error("【DETAIL 设备信息找不到】：{}", criteria.getId());
                if (criteria.getId() != null) {
                    redisUtil.setHash(EQUIPMENT_DETAIL, String.valueOf(criteria.getId()), NULL);
                }
                if (criteria.getName() != null) {
                    redisUtil.setHash(EQUIPMENT_DETAIL, String.valueOf(criteria.getId()), NULL);
                }
            }
        }
        return info == null ? null : Collections.singletonList(info);
    }

    public List<Equipment> detail(EquipmentQueryCriteria criteria, EquipmentSType sType) {
        boolean isReturn = true;
        switch (sType) {
            case NONE:
                break;
            case ID:
                if (criteria.getId() != null) {
                    isReturn = false;
                }
                break;
            case NAME:
                if (criteria.getName() != null) {
                    isReturn = false;
                }
                break;
            case REGISTER_NUMBER:
                if (criteria.getRegisterNumber() != null) {
                    isReturn = false;
                }
                break;
            case FACTORY_NUMBER:
                if (criteria.getFactoryNumber() != null) {
                    isReturn = false;
                }
                break;
            case BK1:
                if (criteria.getBk1() != null) {
                    isReturn = false;
                }
        }
        if (isReturn) {
            return equipmentMapper.detail(criteria);
        }

        Equipment info = null;
        try {
            Object hash = null;
            switch (sType) {
                case ID:
                    hash = redisUtil.getHash(EQUIPMENT_DETAIL + "_" + sType.name(), String.valueOf(criteria.getId()));
                    break;
                case NAME:
                    hash = redisUtil.getHash(EQUIPMENT_DETAIL + "_" + sType.name(), criteria.getName());
                    break;
                case REGISTER_NUMBER:
                    hash = redisUtil.getHash(EQUIPMENT_DETAIL + "_" + sType.name(), criteria.getRegisterNumber());
                    break;
                case FACTORY_NUMBER:
                    hash = redisUtil.getHash(EQUIPMENT_DETAIL + "_" + sType.name(), criteria.getFactoryNumber());
                    break;
                case BK1:
                    hash = redisUtil.getHash(EQUIPMENT_DETAIL + "_" + sType.name(), criteria.getBk1());
                    break;
            }
            if (hash != null){
                info = JSON.parseObject(JSON.toJSONString(hash), Equipment.class);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        //写redis
        if (info == null) {
            List<Equipment> equipments = equipmentMapper.detail(criteria);
            if (!equipments.isEmpty()){
                equipments.forEach(item -> redisUtil.setHash(EQUIPMENT_DETAIL + "_" + sType.name(), item.getName(), item));
            }
            return equipments;
        }
        return Collections.singletonList(info);
    }

    @Override
    public void updateLatestStatus(LatestEquipmentStatus latestEquipmentStatus) {
        if (latestEquipmentStatus.getEqId() == null){
            throw new IllegalArgumentException("Update equipment latest status need to specify corresponding id.");
        }
        equipmentMapper.updateLatestStatus(latestEquipmentStatus);
    }
}
